package com.gec.listener;

import com.gec.dao.MenuDao;
import com.gec.domain.Menu;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * 写侦听器目的:
 *  在 web 应用加载初始化时, 去数据库把角色菜单信息
 *  加载到内存, 存入应用程序域。
 */
public class ContextLifeListener
        implements ServletContextListener {

    private WebApplicationContext webCtx;
    private MenuDao menuDao;

    //String[] roles = {"*","1","2"};
    @Override
    public void contextInitialized(
            ServletContextEvent event) {
        ServletContext context = event.getServletContext();
        //{1}在这个方法中如果获取 Spring IOC 容器中的 Bean
        webCtx = WebApplicationContextUtils.getWebApplicationContext(context);
        //{2}获取 ioc 容器中的 bean
        menuDao = webCtx.getBean(MenuDao.class);
        Map<String, Menu> sysMap;
        Map<String, Menu> genMap;
        try {
            //{1}获取系统菜单
            List<Menu> menus = menuDao.getSysMenus();
            //{2}转成父子菜单格式(方便迭代)
            sysMap = setSubMenus(menus);
            //{3}存入应用域
            context.setAttribute("sysMap", sysMap);

            //{4}生成通用菜单 [给员工使用的]
            genMap = getGeneralMenu();
            //{5}存入通用菜单到应用域
            context.setAttribute("genMap", genMap);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Map<String, Menu> getGeneralMenu() {
        Map<String, Menu> menuMap = new HashMap();
        //id, pID, menuName, mapping, visible
        Menu M1 = new Menu("G001,m,请假流程,/Leave,1");
        Menu M2 = new Menu("G002,m,报销流程,/xxx,1");

        Menu M1_1 = new Menu("G010,m,我要请假,/Leave/showLeaveForm,1");
        Menu M1_2 = new Menu("G011,m,待我审批的,/Leave/waitMyApprove,1");
        Menu M1_3 = new Menu("G012,m,我发起的,/Leave/myInitiate,1");
        Menu M1_4 = new Menu("G013,m,我已审批的,/Leave/myApproved,1");
        M1.addMenu(M1_1);
        M1.addMenu(M1_2);
        M1.addMenu(M1_3);
        M1.addMenu(M1_4);

        Menu M2_1 = new Menu("G010,m,我要报销,/Reim/showReimForm,1");
        Menu M2_2 = new Menu("G011,m,待我审批的,/Reim/waitMyApprove,1");
        Menu M2_3 = new Menu("G012,m,我发起的,/Reim/myInitiate,1");
        Menu M2_4 = new Menu("G013,m,我已审批的,/Reim/myApproved,1");
        M2.addMenu(M2_1);
        M2.addMenu(M2_2);
        M2.addMenu(M2_3);
        M2.addMenu(M2_4);

        menuMap.put(M1.getId(), M1);
        menuMap.put(M2.getId(), M2);

        return menuMap;
    }

    private Map<String, Menu> setSubMenus(
            List<Menu> list) {
        Map<String, Menu> menuMap = new HashMap();
        Menu M;
        //{1}先存入所有的一级菜单进来(保守做法。)
        for (Menu menu : list) {
            String pID = menu.getParentId();
            String menuId = menu.getId();
            //{1}先看这个是不是一级菜单
            if ("m".equals(pID)) {
                //{2}一级菜单, 先从 menuMap 根据 id 获取出 Menu
                M = menuMap.get(menuId);
                if (M == null) {
                    menuMap.put(menuId, menu);
//                    System.out.println("{M}添加父菜单:" + menu);
                }
            }
        }
        //{2}这里迭代所有二级菜单
        for (Menu menu : list) {
            String pID = menu.getParentId();
            String menuId = menu.getId();
            //{1}先看这个是不是二级菜单
            if (!"m".equals(pID)) {
                //{2}根据子菜单的父 ID, 取出对应的父菜单
                M = menuMap.get(pID);
                if (M != null) {
                    M.addMenu(menu);
//                    System.out.println("{M}添加子菜单:" + menu);
                }
            }
        }
        return menuMap;
    }

    //{ps}不要写错方法。
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
    }

}
